package com.vietnam.power.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.vietnam.power.constant.AppConfigurationConstant;
import com.vietnam.power.constant.GeneralConstant;
import com.vietnam.power.dao.TransactionDao;
import com.vietnam.power.domain.SaleOrder;
import com.vietnam.power.domain.TransactionSearchCriteria;
import com.vietnam.power.persitence.PatronInfo;
import com.vietnam.power.persitence.PaymentMethod;
import com.vietnam.power.persitence.Product;
import com.vietnam.power.persitence.Transaction;
import com.vietnam.power.persitence.TxnProduct;
import com.vietnam.power.service.TransactionService;
import com.vietnam.power.util.MessageUtil;

@Service
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public class TransactionServiceImpl implements TransactionService {
	// TODO: hard code time zone vietnam
	private static final String timezone = GeneralConstant.VIET_NAM_TIMEZONE;
	@Autowired
	private TransactionDao transactionDao;

	public void createTransaction(SaleOrder saleOrder) {
		// create txn ref number
		saleOrder.setTransactionRefNum(MessageUtil.generateTransactionRefNum(timezone));
		Transaction txn = new Transaction();

		txn.setTransactionRefNumber(saleOrder.getTransactionRefNum());
		txn.setOrderStatus(AppConfigurationConstant.TransactionStatus.PENDING.getOrderStatus());
		txn.setPaymentMethod(new PaymentMethod(saleOrder.getPatronInfo().getPaymentId()));
		txn.setRemark(saleOrder.getPatronInfo().getRemark());
		txn.setTotalPaid(saleOrder.getTotalPrice());

		PatronInfo pi = new PatronInfo();
		pi.setFullName(saleOrder.getPatronInfo().getFullName());
		pi.setEmail(saleOrder.getPatronInfo().getEmail());
		pi.setPhone(saleOrder.getPatronInfo().getPhone());
		pi.setAddress(saleOrder.getPatronInfo().getAddress());
		txn.setPatronInfo(pi);

		List<TxnProduct> txnLst = new ArrayList<TxnProduct>();

		Set<com.vietnam.power.domain.Product> products = saleOrder.getProducts();

		Iterator<com.vietnam.power.domain.Product> itr = products.iterator();
		while (itr.hasNext()) {
			com.vietnam.power.domain.Product p = itr.next();
			TxnProduct txnP = new TxnProduct();
			txnP.setTransaction(txn);
			txnP.setProduct(new Product(p.getId()));
			txnP.setQuantity(p.getQuantity());
			txnP.setUnitPrice(p.getUnitPrice());
			txnLst.add(txnP);
		}

		txn.setTxnProducts(txnLst);
		transactionDao.createTransaction(txn);
	}

	public void updateTransaction(com.vietnam.power.domain.Transaction saleOrder) {
		Transaction txn = transactionDao.getTransactionById(saleOrder.getId());
		txn.setOrderStatus(saleOrder.getOrderStatus());
		transactionDao.updateTransaction(txn);
	}
	
	public void updatePatronInfo(com.vietnam.power.domain.PatronInfo patronInfo) {
		PatronInfo pi = transactionDao.getPatronInfoById(patronInfo.getId());
		
		patronInfo.convertToPersist(pi);
		
		transactionDao.updatePatron(pi);
	}
	
	public com.vietnam.power.domain.PatronInfo getPatronInfoById(int id) {
		com.vietnam.power.domain.PatronInfo pi = new com.vietnam.power.domain.PatronInfo();
		
		pi.convertToDomain(transactionDao.getPatronInfoById(id));
		
		return pi;
	}

	public com.vietnam.power.domain.Transaction getTransactionById(int id) {
		com.vietnam.power.domain.Transaction order = new com.vietnam.power.domain.Transaction();
		Transaction txn = transactionDao.getTransactionById(id);
		
		order.setTransactionRefNum(txn.getTransactionRefNumber());
		order.setCreatedDate(txn.getCreatedDate());
		order.setOrderStatus(txn.getOrderStatus());
		order.setId(txn.getId());
		order.setTotalPrice(txn.getTotalPaid());
		order.setPaymentMethodName(txn.getPaymentMethod().getName());
		order.setRemark(txn.getRemark());

		//product
		for (TxnProduct txnP : txn.getTxnProducts()) {
			com.vietnam.power.domain.Product p = new com.vietnam.power.domain.Product();
			p.convertToDomain(txnP.getProduct());
			p.setUnitPrice(txnP.getUnitPrice());
			p.setQuantity(txnP.getQuantity());
			order.addProducts(p);
		}
		
		com.vietnam.power.domain.PatronInfo pi = new com.vietnam.power.domain.PatronInfo();
		pi.convertToDomain(txn.getPatronInfo());
		
		order.setPatronInfo(pi);
		
		return order;
	}

	public List<com.vietnam.power.domain.Transaction> searchTransaction(TransactionSearchCriteria s) {
		List<com.vietnam.power.domain.Transaction> lst = new ArrayList<com.vietnam.power.domain.Transaction>();
		List<Transaction> txnList = transactionDao.searchTransaction(s);
		
		for (Transaction txn : txnList) {
			com.vietnam.power.domain.Transaction order = new com.vietnam.power.domain.Transaction();
			order.setTransactionRefNum(txn.getTransactionRefNumber());
			order.setCreatedDate(txn.getCreatedDate());
			order.setOrderStatus(txn.getOrderStatus());
			order.setTotalPrice(txn.getTotalPaid());
			order.setId(txn.getId());
			
			com.vietnam.power.domain.PatronInfo pi = new com.vietnam.power.domain.PatronInfo();
			pi.convertToDomain(txn.getPatronInfo());
			
			order.setPatronInfo(pi);
			
			lst.add(order);
		}
		
		return lst;
	}

}
